#include "stdafx.h"
#include "ObjectManager.h"
#include "Object.h"
#include "guiMediator.h"

CObjectManager::CObjectManager()
{
    m_curObjId = 0;
    m_guimediator = NULL;
}

CObjectManager::~CObjectManager()
{
    DeleteAllObj();
}

void CObjectManager::Update( int diff )
{
    m_selectedEntities.clear();
    for( ObjectMap::iterator iter = m_objects.begin(); iter != m_objects.end(); iter++ )
    {
        sgObject *obj = iter->second;
        obj->Update( diff );
    }
    CheckSelected();
    DispatchMessage();
}

void CObjectManager::Render()
{
    for( ObjectMap::iterator iter = m_objects.begin(); iter != m_objects.end(); iter++ )
    {
        sgObject *obj = iter->second;
        obj->Render( );
    }
}

void CObjectManager::DeleteAllObj()
{
    for( ObjectMap::iterator iter = m_objects.begin(); iter != m_objects.end(); iter++ )
    {
        SAFE_DELETE( iter->second );
    }
    m_objects.clear();
}

sgObject * CObjectManager::CreateObject( int classtype )
{
    ObjectCreator creator = GetCreator( classtype );
    if( creator )
    {
        return creator();
    }
    return NULL;
}

ObjectCreator CObjectManager::GetCreator( int classtype )
{
    CreatorMap::iterator iter = m_creators.find( classtype );
    if( iter == m_creators.end() )
    {
        return NULL;
    }
    return iter->second;
}

bool CObjectManager::RegisteCreator( int classtype, ObjectCreator creator )
{
    if( GetCreator( classtype ) )
        return false;
    m_creators.insert( std::make_pair<int, ObjectCreator>(classtype, creator) );
    return true;
}

bool CObjectManager::AddObject( sgObject *obj )
{
    CHECK_PTR(obj, false);
    if( GetObject( obj->GetID()) != NULL )
        return false;
    m_objects[obj->GetID()] = obj;
    return true;
}

sgObject * CObjectManager::GetObject( int id )
{
    ObjectMap::iterator iter = m_objects.find(id);
    if( iter != m_objects.end() )
    {
        return iter->second;
    }
    return NULL;
}

int CObjectManager::GenerateObjectID()
{
    m_curObjId++;
    while( GetObject(m_curObjId) )
    {
        m_curObjId++;
    }
    return m_curObjId;
}

bool CObjectManager::RemoveObject( sgObject *obj )
{
    if( obj == NULL )
        return false;
    ObjectMap::iterator iter = m_objects.find( obj->GetID() );
    if( iter != m_objects.end() )
    {
        m_objects.erase( iter );
        return true;
    }
    return false;
}

void CObjectManager::AddSelectedEntity( sgEntity *entity )
{
    m_selectedEntities.push_back( entity );
}

void CObjectManager::SendMessage( sgMessage *msg )
{
    m_messages.push( msg );
}

void CObjectManager::DispatchMessage()
{
    while( !m_messages.empty() )
    {
        sgMessage *msg = m_messages.front();
        msg->to->ProcessMessage( msg );
        SAFE_DELETE( msg );
        m_messages.pop( );
    }
}

void CObjectManager::CheckSelected()
{
    if( m_selectedEntities.size() > 0 )
    {
        sgEntity *selected = m_selectedEntities.at( 0 );
        sgMessage *msg = new sgMessage;
        msg->to = (sgObject*)selected;
        msg->type = MSG_SELECTED;
        SendMessage( msg );
    }
}

guiMediator * CObjectManager::GetGuiMediator()
{
    return m_guimediator;
}

void CObjectManager::SetGuiMediator( guiMediator *m )
{
    if( m == NULL )
        return;
    if( m_guimediator )
    {
        RemoveObject( m_guimediator );
        delete m_guimediator;
        m_guimediator = NULL;
    }
    m_guimediator = m;
    AddObject( m );
}

void CObjectManager::SendMessageToGUI( sgMessage *msg )
{
    if( m_guimediator == NULL )
        return;
    msg->to = m_guimediator;
    SendMessage( msg );
}

void CObjectManager::SaveObjects()
{
    CXmlSerialize s(Serialize_Save);
    ObjectMap::iterator iter = m_objects.begin();
    while( iter != m_objects.end() )
    {
        sgObject *obj = iter->second;
        s&MAKE_PAIR(obj,"Object");
        iter++;
    }
    s.SaveToFile("save.xml");
}

void CObjectManager::LoadObjects()
{
    sgObject obj;
    
    CXmlSerialize s(Serialize_Load);
    if(false == s.LoadFromFile("save.xml"))
        return;
    m_objects.clear();
    while( true )
    {
        s&MAKE_PAIR(obj,"Object");
        if( s.GetLastLoad() == false )
        {
            break;
        }
        sgObject *realobj = CreateObject( obj.GetClassType() );
        AddObject( realobj );
    }
    s.SetToBegin();
    ObjectMap::iterator iter = m_objects.begin();
    while( iter != m_objects.end() )
    {
        sgObject *obj = iter->second;
        s&MAKE_PAIR(obj,"Object");
        iter++;
    }
}
